import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import { Messager, createRandomId } from '@/utils'
import settings from '@/config'

// 初始化跨源通信实例
const messager = new Messager(settings.decorateOrigin)
Vue.use(Vuex)

// 动态引入 modules，利用 webpack 的 require.context 方法，自动引入 modules 目录下的所有模块
const modulesFiles = require.context('./modules', true, /\.js$/) // modulesFiles.keys() 返回文件数组
let modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // ./index.js => index
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  modules[moduleName] = modulesFiles(modulePath).default
  return modules
}, {})

const emptyPageData = {
  id: '',
  name: '页面标题',
  shareDesc: '', // 微信分享文案
  shareImage: '', // 微信分享图片
  backgroundColor: '#fff', // 背景颜色
  backgroundImage: '', // 背景图片
  backgroundPosition: 'top', // 页面背景位置
  componentList: [] // 组件列表
}
const store = new Vuex.Store({
  state: {
    // 当前组件是否正在拖动
    dragActive: false,
    // 当前正在拖动的组件
    dragComponent: {},
    // 存储当前页面的数据
    pageData: JSON.parse(JSON.stringify(emptyPageData)),
    // iframe 的高度 previewHeight
    previewHeight: '',
    // 页面中组件高度
    componentsTopList: [],
    // 拖动组件要添加的位置
    addComponentIndex: null,
    // 当前选中的组件 id
    activeComponentId: null,
    // 当前设置内容，1-页面 2-组件
    setType: 1,
    // 公共上传弹窗的显示
    dialogImageVisible: false,
    // 上传图片成功的回调事件
    upLoadImgSuccess: null,
    sidebar: {
      opened: true,
      withoutAnimation: false
    },
    wxParams: JSON.stringify({isLogin: true}) // h5页面参数
  },
  mutations: {
    TOGGLE_SIDEBAR: state => {
      state.sidebar.opened = !state.sidebar.opened
      state.sidebar.withoutAnimation = false
    },
    // 修改组件拖动的状态
    SET_DRAG_STATE(state, value) {
      state.dragActive = value
    },
    // 设置当前正在拖动的组件对象
    SET_DRAG_COMPONENT(state, value) {
      state.dragComponent = value
    },
    // 页面更新方法
    UPDATE_COMPONENT(state, { data }) {
      state.pageData = data || {}
    },
    // 向H5端发送修改后的数据
    VIEW_UPDATE(state) {
      messager.emit('pageChange', {
        value: state.pageData
      })
    },
    // 获取 H5 组件高度并更新
    UPDATE_PAGE_HEIGHT(state, { height, list }) {
      state.previewHeight = height
      state.componentsTopList = list
    },
    // 修改通过组件要添加的位置
    SET_DRAG_INDEX(state, value) {
      state.addComponentIndex = value
    },
    // 向H5页面发送预添加组件
    VIEW_ADD_PREVIEW(state, index) {
      messager.emit('setPreview', index)
    },
    // 修改选中组件 id
    SET_ACTIVE_ID(state, value) {
      state.activeComponentId = value
    },
    // 向 H5 页面发送选中组件 id
    VIEW_SET_ACTIVE (state, id) {
      messager.emit('setActive', id)
    },
    SET_SETTYPE(state, value) {
      state.setType = value
    },
    // 页面新增
    ADD_COMPONENT(state, { index, data }) {
      const component = JSON.parse(JSON.stringify(data))
      // 生成随机ID
      const id = component.data.component + '-' + createRandomId()
      component.id = id
      if (component.iconClass) { delete component.iconClass } // 清除后台使用的图标
      state.pageData.componentList.splice(index, 0, component) // 插入选择的组件
      // 设置新加入的组件为选中状态
      this.commit('SET_ACTIVE_ID', id)
      // 更新 H5 区域选中状态
      this.commit('VIEW_SET_ACTIVE', id)
      // 更新页面编辑类型为组件
      this.commit('SET_SETTYPE', 2)
      // 重置拖动组件要添加的位置
      this.commit('SET_DRAG_INDEX', null)
    },
    // 页面删除
    DELETE_COMPONENT(state, { index }) {
      // 清空页面全部组件
      if (index === 'all') {
        state.pageData.componentList = []
      } else if (typeof index === 'number') {
        // 删除页面单个组件
        state.pageData.componentList.splice(index, 1)
      }
    },
    // 页面编辑
    EDIT_COMPONENT(state, { id, data }) {
      const component = state.pageData.componentList.find(item => item.id === id)
      if (component) component.data = data
    },
    // 页面编辑组件的方法
    SET_PAGE_CONFIG(state, config) {
      Object.keys(config).forEach((key) => {
        state.pageData[key] = config[key]
      })
      // 同步数据给 crs
      this.commit('VIEW_UPDATE')
    },
    // 修改上传图片弹窗是否显示
    SET_UPIMAGE_VISIBLE(state, value) {
      state.dialogImageVisible = value
    },
    // 修改上传成功的回调事件
    SET_UPIMAGE_FUC(state, value) {
      state.upLoadImgSuccess = value
    }
  },
  actions: {
    // 跨源通信H5数据的监听
    initMessage({ commit }) {
      messager.on('pageHeightChange', data => {
        let height = data.height ? data.height + 72 : 768
        let list = data.componentsTopList || []
        commit('UPDATE_PAGE_HEIGHT', { height, list })
      })
      // 监听 crs 页面选中项 id 的变化
      messager.on('setActive', id => {
        commit('SET_ACTIVE_ID', id)
        commit('SET_SETTYPE', 2)
      })
    },
    pageChange({ commit }, changeValue) {
      const commitObj = {
        add: 'ADD_COMPONENT',
        delete: 'DELETE_COMPONENT',
        edit: 'EDIT_COMPONENT'
      }
      commitObj[changeValue.type] && commit(commitObj[changeValue.type], changeValue)
      // 向H5页面发送预添加组件
      commit('VIEW_UPDATE')
    },
    toggleSideBar({ commit }) {
      commit('TOGGLE_SIDEBAR')
    }
  },
  getters,
  modules
})

Vue.store = store

export default store
